package powscl

import (
	//"fmt"
	"github.com/ChimeraCoder/anaconda"
	"math"
	"net/url"
	"strconv"
	"strings"
)

const (
	winScl  = 0.9
	lossScl = 0.6
)

var (
	Matches []Match
)

type Team struct {
	TeamNumber      int
	TeamName, Notes string

	Played int

	PowRank, OffRank, DefRank float64
	TelRank, AutRank          float64

	AvgSumScore  float64
	AvgTeleScore float64
	AvgAutoScore float64
	AvgPenScore  float64

	QP, RP            float64
	Wins, Losses, Tie float64
	WinRate           float64
}

type Match struct {
	RedTeams  []int
	BlueTeams []int
	Number    int

	RScore, BScore int
	RAuto, BAuto   int
	RTele, BTele   int
	RPen, BPen     int
}

func UpdateTeamList(matchList []Match, oldList map[int]Team) map[int]Team {
	newList := make(map[int]Team)
	for q := 0; q < len(matchList); q++ {
		for t := 0; t < len(matchList[q].RedTeams); t++ {
			newList[matchList[q].RedTeams[t]] = oldList[matchList[q].RedTeams[t]]
		}
		for t := 0; t < len(matchList[q].BlueTeams); t++ {
			newList[matchList[q].BlueTeams[t]] = oldList[matchList[q].BlueTeams[t]]
		}
	}
	return newList
}

func PrelimCalc(matchList []Match, teamList map[int]Team) map[int]Team {
	type TeamTempDat struct {
		AutoScore float64
		TeleScore float64

		Penalties float64
		Played    float64

		QP, RP         float64
		Win, Loss, Tie float64
	}
	teamDatMap := make(map[int]TeamTempDat)

	for q := 0; q < len(matchList); q++ {
		var match = matchList[q]
		for t := 0; t < 3; t++ {
			var rTeamNum = matchList[q].RedTeams[t]
			var bTeamNum = matchList[q].BlueTeams[t]
			var rTeamDat = teamDatMap[rTeamNum]
			var bTeamDat = teamDatMap[bTeamNum]
			rTeamDat.Played++
			bTeamDat.Played++

			//teamdat.RP += int(math.Min(float64(match.RScore), float64(match.BScore)))

			rTeamDat.AutoScore += float64(match.RAuto)
			rTeamDat.TeleScore += float64(match.RTele)
			rTeamDat.Penalties += float64(match.BPen) //Use opposite team's penalty score
			if match.RScore > match.BScore {
				rTeamDat.QP += 2
				rTeamDat.Win++
			} else {
				if match.RScore == match.BScore {
					rTeamDat.QP += 1
					rTeamDat.Tie++
				} else {
					rTeamDat.Loss++
				}
			}

			bTeamDat.AutoScore += float64(match.BAuto)
			bTeamDat.TeleScore += float64(match.BTele)
			bTeamDat.Penalties += float64(match.RPen) //Use opposite team's penalty score
			if match.BScore > match.RScore {
				bTeamDat.QP += 2
				bTeamDat.Win++
			} else {
				if match.BScore == match.RScore {
					bTeamDat.QP += 1
					bTeamDat.Tie++
				} else {
					bTeamDat.Loss++
				}
			}
		}
	}

	for i, v := range teamDatMap {
		var tmp = teamList[i]
		tmp.AvgAutoScore = float64(v.AutoScore) / float64(v.Played)
		tmp.AvgTeleScore = float64(v.TeleScore) / float64(v.Played)
		tmp.AvgSumScore = tmp.AvgAutoScore + tmp.AvgTeleScore
		tmp.AvgPenScore = float64(v.Penalties) / float64(v.Played)

		tmp.QP = v.QP
		tmp.RP = v.RP
		tmp.Wins = v.Win
		tmp.Losses = v.Loss
		tmp.WinRate = 100 * (float64(v.Win) / float64(v.Win+v.Loss))

		teamList[i] = tmp
	}

	return teamList
}

func ScoreCalc(matchList []Match, teamList map[int]Team) map[int]Team {
	type TempTeamDat struct {
		OffRank, DefRank float64
		TelRank, AutRank float64

		Played int
	}
	teamDatMap := make(map[int]TempTeamDat)

	for q := 0; q < len(matchList); q++ {
		var match = matchList[q]
		var rTeam1 = teamList[matchList[q].RedTeams[0]]
		var rTeam2 = teamList[matchList[q].RedTeams[1]]
		var rTeam3 = teamList[matchList[q].RedTeams[2]]
		var bTeam1 = teamList[matchList[q].BlueTeams[0]]
		var bTeam2 = teamList[matchList[q].BlueTeams[1]]
		var bTeam3 = teamList[matchList[q].BlueTeams[2]]
		// var rTeam1Dat = teamDatMap[matchList[q].RedTeams[0]]
		// var rTeam2Dat = teamDatMap[matchList[q].RedTeams[1]]
		// var rTeam3Dat = teamDatMap[matchList[q].RedTeams[2]]
		// var bTeam1Dat = teamDatMap[matchList[q].BlueTeams[0]]
		// var bTeam2Dat = teamDatMap[matchList[q].BlueTeams[1]]
		// var bTeam3Dat = teamDatMap[matchList[q].BlueTeams[2]]
		rTeam1.Played++
		rTeam2.Played++
		rTeam3.Played++
		bTeam1.Played++
		bTeam2.Played++
		bTeam3.Played++

		redScl := winScl
		blueScl := winScl
		if match.BScore > match.RScore {
			redScl = lossScl
		}
		if match.RScore > match.BScore {
			blueScl = lossScl
		}

		rTeam1.TelRank += redScl * float64(float64(match.RTele)-rTeam2.AvgTeleScore-rTeam3.AvgTeleScore) //Teleop
		rTeam2.TelRank += redScl * float64(float64(match.RTele)-rTeam1.AvgTeleScore-rTeam3.AvgTeleScore)
		rTeam3.TelRank += redScl * float64(float64(match.RTele)-rTeam1.AvgTeleScore-rTeam2.AvgTeleScore)
		rTeam1.AutRank += redScl * float64(float64(match.RAuto)-rTeam2.AvgAutoScore-rTeam3.AvgAutoScore) //Autonomous
		rTeam2.AutRank += redScl * float64(float64(match.RAuto)-rTeam1.AvgAutoScore-rTeam3.AvgAutoScore)
		rTeam3.AutRank += redScl * float64(float64(match.RAuto)-rTeam1.AvgAutoScore-rTeam2.AvgAutoScore)
		rTeam1.OffRank += redScl * float64(float64(match.RScore)-float64(match.RPen)-rTeam2.AvgSumScore-rTeam3.AvgSumScore) //Autonomous
		rTeam2.OffRank += redScl * float64(float64(match.RScore)-float64(match.RPen)-rTeam1.AvgSumScore-rTeam3.AvgSumScore)
		rTeam3.OffRank += redScl * float64(float64(match.RScore)-float64(match.RPen)-rTeam1.AvgSumScore-rTeam2.AvgSumScore)
		rTeam1.DefRank += blueScl * float64(float64(match.BScore)-float64(match.BPen)-bTeam2.AvgSumScore-bTeam2.AvgSumScore-bTeam3.AvgSumScore) //Defensive score
		rTeam2.DefRank += blueScl * float64(float64(match.BScore)-float64(match.BPen)-bTeam1.AvgSumScore-bTeam2.AvgSumScore-bTeam3.AvgSumScore)
		rTeam3.DefRank += blueScl * float64(float64(match.BScore)-float64(match.BPen)-bTeam1.AvgSumScore-bTeam2.AvgSumScore-bTeam2.AvgSumScore)
	}

	var max = float64(0)
	for i, v := range teamDatMap {
		var tmp = teamList[i]
		tmp.TeamNumber = i
		if tmp.TeamName == "" || tmp.TeamName == "[NONAME]" {
			tmp.TeamName = "N/A"
		}
		tmp.AutRank = v.AutRank / float64(v.Played)
		tmp.TelRank = v.TelRank / float64(v.Played)
		tmp.DefRank = v.DefRank / float64(v.Played)
		tmp.OffRank = v.OffRank / float64(v.Played)
		teamList[i] = tmp
		if math.Abs(float64(tmp.PowRank)) > max {
			max = math.Abs(float64(tmp.PowRank))
		}
	}

	return teamList
}

func GetMatches() {
	anaconda.SetConsumerKey("1Jvo1RB3HeYndrjMrD0vQ")
	anaconda.SetConsumerSecret("fAE6xqCzz9qHKip5sNLT7LzDCXRoIqQTOUjufp0cHEo")
	api := anaconda.NewTwitterApi("2371420178-CUHTIeXy2Pio2GhNrVM6MNmE4tiCZC3KzW2huvk", "aLKduFECY4b0h4h7exIXEa0sfPDuM8Rum5nwL4rMtaIHy")
	v := url.Values{}
	var tmpMatch Match
	v.Set("count", `100`)
	searchResult, _ := api.GetSearch(`"TY Q" #FRCCASB from:frcfms`, v)
	for _, tweet := range searchResult {
		//tweetTime, _ := tweet.CreatedAtTime()
		scores := strings.Split(tweet.Text, " ")
		for i := 0; i < len(scores); i++ {
			switch scores[i] {
			case "MC":
				i++
				tmpMatch.Number, _ = strconv.Atoi(scores[i])
				break
			case "RF":
				i++
				tmpMatch.RScore, _ = strconv.Atoi(scores[i])
				break
			case "BF":
				i++
				tmpMatch.BScore, _ = strconv.Atoi(scores[i])
				break
			case "RA":
				i++
				one, _ := strconv.Atoi(scores[i])
				i++
				two, _ := strconv.Atoi(scores[i])
				i++
				three, _ := strconv.Atoi(scores[i])
				tmpMatch.RedTeams = []int{one, two, three}
				break
			case "BA":
				i++
				one, _ := strconv.Atoi(scores[i])
				i++
				two, _ := strconv.Atoi(scores[i])
				i++
				three, _ := strconv.Atoi(scores[i])
				tmpMatch.BlueTeams = []int{one, two, three}
				break
			case "RFP":
				i++
				tmpMatch.RPen, _ = strconv.Atoi(scores[i])
				break
			case "BFP":
				i++
				tmpMatch.BPen, _ = strconv.Atoi(scores[i])
				break
			case "RHS":
				i++
				tmpMatch.RAuto, _ = strconv.Atoi(scores[i])
				break
			case "BHS":
				i++
				tmpMatch.BAuto, _ = strconv.Atoi(scores[i])
				break
			case "RTS":
				i++
				tmpMatch.RTele, _ = strconv.Atoi(scores[i])
				break
			case "BTS":
				i++
				tmpMatch.BTele, _ = strconv.Atoi(scores[i])
				break
			default:
				break

			}
		}
		Matches = append(Matches, tmpMatch)
	}
}
